package com.yl.zqy.service.impl.login;

import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.yl.zqy.common.CustomException;
import com.yl.zqy.common.Result;
import com.yl.zqy.dto.SysMenuDTO;
import com.yl.zqy.dto.SysRoleUserDTO;
import com.yl.zqy.entity.sys.SysUser;
import com.yl.zqy.enums.ResultCode;
import com.yl.zqy.service.login.LoginService;
import com.yl.zqy.service.sys.SysMenuService;
import com.yl.zqy.service.sys.SysRoleService;
import com.yl.zqy.service.sys.SysUserService;
import com.yl.zqy.vo.login.LoginVo;
import com.yl.zqy.vo.login.UserPwdVo;
import com.yl.zqy.vo.user.UserInfoVo;
import com.yl.zqy.vo.user.UserInstanceVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @Description 登录服务接口实现
 * @Author liang.yu
 * @Date 2024/3/24 12:51
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class LoginServiceImpl implements LoginService {
    private final SysUserService userService;
    private final SysRoleService roleService;

    private final SysMenuService menuService;

    @Override
    public Result<UserInfoVo> login(LoginVo vo) {
        UserInfoVo userInfo = new UserInfoVo();
        // 判断当前请求Token是否过期
        String token = StpUtil.getTokenValue();
        Object loginId = StpUtil.getLoginIdByToken(token);
        if (ObjectUtils.isNotEmpty(loginId)) {
            userInfo.setUserId(StpUtil.getLoginIdAsString());
            userInfo.setUsername(StpUtil.getExtra("username").toString());
            userInfo.setRealName(StpUtil.getExtra("realName").toString());
            userInfo.setRoles((List<String>) StpUtil.getExtra("roles"));
            userInfo.setToken(token);
            StpUtil.updateLastActiveToNow();
            return Result.ok(userInfo);
        } else {
            // 登录操作
            SysUser user = userService.getUserByLogin(vo);

            if (user != null && ObjectUtils.isNotEmpty(user)) {
                List<String> userByRole = roleService.getUserByRole(user.getId());
                userInfo.setUserId(user.getId());
                userInfo.setUsername(user.getUsername());
                userInfo.setRealName(user.getRealName());
                userInfo.setRoles(userByRole);

                SaLoginModel loginModel = new SaLoginModel();
                loginModel.setExtra("userId", userInfo.getUserId());
                loginModel.setExtra("username", userInfo.getUsername());
                loginModel.setExtra("realName", userInfo.getRealName());
                loginModel.setExtra("roles", userByRole);
                StpUtil.login(userInfo.getUserId(), loginModel);
                userInfo.setToken(StpUtil.getTokenValue());
                return Result.ok(userInfo);
            } else {
                return Result.error(null, ResultCode.LOGIN_ERROR.getCode(), "账号密码不正确，请重新登录");
            }
        }
    }

    @Override
    public void logout() {
        StpUtil.logout();   // 会话注销
    }

    @Override
    public Result<UserInfoVo> getSubject() {
        SysRoleUserDTO userDTO = userService.getUserInfo(StpUtil.getLoginIdAsString());
        UserInfoVo userInfo = new UserInfoVo();
        userInfo.setUserId(StpUtil.getLoginIdAsString());
        userInfo.setUsername(StpUtil.getExtra("username").toString());
        userInfo.setRealName(StpUtil.getExtra("realName").toString());
        userInfo.setRoles((List<String>) StpUtil.getExtra("roles"));
        userInfo.setToken(StpUtil.getTokenValue());
        userInfo.setHeadUrl(userDTO.getHeadUrl());
        userInfo.setMobile(userDTO.getMobile());
        userInfo.setEmail(userDTO.getEmail());
        userInfo.setDeptId(userDTO.getDeptId());
        userInfo.setDeptName(userDTO.getDeptName());
        userInfo.setGender(userDTO.getGender());

        StpUtil.updateLastActiveToNow();
        return Result.ok(userInfo);
    }

    @Override
    public Result<List<String>> getPermission() {
        if (StringUtils.isBlank(StpUtil.getLoginIdAsString())) {
            throw new CustomException(ResultCode.PARAMS_ERROR, "未获取到当前用户信息！");
        }
        return Result.ok(menuService.getUserByMenusPermission(StpUtil.getLoginIdAsString()));
    }

    @Override
    public Result<List<SysMenuDTO>> getMenus() {
        return Result.ok(menuService.menus());
    }

    @Override
    public Result<Boolean> updatePwd(UserPwdVo vo) {
        return userService.updatePwd(vo);
    }
}
